package com.wv1124.cashtest;

import androidx.appcompat.app.AppCompatActivity;

import android.content.Context;
import android.os.Bundle;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

    private TextView textView;

    EditText mSearchContentEditText;

    private StringBuilder mResult;
    private int count = 0;

    private Button cancelBtn;
    private Button searchBtn;
    private Button goSearchBtn;
    private LinearLayout bodyLayout;

    private boolean mCaps;

    private static String[] mKeyboardDeviceNames = {"virtual"};


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        this.mResult = new StringBuilder();
        textView = MainActivity.this.findViewById(R.id.showTxt);
        mSearchContentEditText = MainActivity.this.findViewById(R.id.edittext_search_content);

        bodyLayout = MainActivity.this.findViewById(R.id.body);
        bodyLayout.setOnClickListener((View v ) -> {
            resetSearch();
        });

        // 取消
        cancelBtn = MainActivity.this.findViewById(R.id.cancel);
        cancelBtn.setOnClickListener((View v) -> {
            resetSearch();
        });

        // 搜索
        searchBtn = MainActivity.this.findViewById(R.id.search);
        searchBtn.setOnClickListener((View v) -> {
            showScanResult(mSearchContentEditText.getText().toString());
            resetSearch();
        });

        // 显示搜索;
        goSearchBtn = MainActivity.this.findViewById(R.id.goSearch);
        goSearchBtn.setOnClickListener((View v) -> {
            mSearchContentEditText.setVisibility(View.VISIBLE);
            mSearchContentEditText.requestFocus();

            InputMethodManager imm = (InputMethodManager) MainActivity.this.getSystemService(Context.INPUT_METHOD_SERVICE);
            mSearchContentEditText.postDelayed(() -> imm.showSoftInput(mSearchContentEditText, InputMethodManager.SHOW_IMPLICIT), 200L);

            mSearchContentEditText.setSelection(mSearchContentEditText.getText().toString().length());
            mSearchContentEditText.setOnFocusChangeListener((vi, hasFocus) -> {
                if (!hasFocus)
                {
                    hideSoftInput();
                }
            });
        });

        resetSearch();
    }

    private void hideSoftInput() {
        InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
        imm.toggleSoftInput(0, InputMethodManager.HIDE_NOT_ALWAYS);
    }

    private void resetSearch() {
        mSearchContentEditText.setText("");
        mSearchContentEditText.clearFocus();
        mSearchContentEditText.setVisibility(View.INVISIBLE);
        hideSoftInput();
    }

    private void showScanResult(String code) {
        String showStr = "第" + count + "次扫码结果：" + code;
//        Toast.makeText( MainActivity.this,  showStr, 1).show();
        textView.setText(showStr);
        count++;
    }

    @Override
    public boolean dispatchKeyEvent(KeyEvent event)
    {
        Log.i("KeyEvent", "输入事件：" + event.getAction() + " name=" + event.getDevice().getName().toLowerCase() + " other=" + event.toString());
        if (!this.isSoftKeyboardEvent(event))
        {
            this.analysisKeyEvent(event);
            return true;
        }
        return super.dispatchKeyEvent(event);
    }

    /**
     * 是否为软键盘事件
     *
     * @param event KeyEvent
     * @return
     */
    public boolean isSoftKeyboardEvent(KeyEvent event)
    {
        boolean isSoftKeyboard = false;
        if (event != null && event.getDevice() != null)
        {
            String deviceLowerName = event.getDevice().getName().toLowerCase();
            for (String deviceName : mKeyboardDeviceNames)
            {
                if (deviceLowerName.contains(deviceName))
                {
                    isSoftKeyboard = true;
                }
            }
        }
        return isSoftKeyboard;
    }


    /**
     * 扫码设备事件解析
     * 【商米扫码枪 大小写不敏感】
     */
    public void analysisKeyEvent(KeyEvent event)
    {

        int keyCode = event.getKeyCode();
        checkLetterStatus(event);
        if (event.getAction() == KeyEvent.ACTION_UP)
        {
            char aChar = getInputCode(mCaps, event.getKeyCode());
            if (aChar != 0)
            {
                mResult.append(aChar);
            }

            if (keyCode == KeyEvent.KEYCODE_ENTER)
            {
                String code = mResult.toString();
                Log.i("KeyEvent 扫码结果", code);
                this.showScanResult(code);
                // 清除缓存
                mResult.delete(0, mResult.length());
            }
        }
    }


    /**
     * 判断大小写
     */
    private void checkLetterStatus(KeyEvent event)
    {
        int keyCode = event.getKeyCode();
        if (keyCode == KeyEvent.KEYCODE_SHIFT_RIGHT || keyCode == KeyEvent.KEYCODE_SHIFT_LEFT)
        {
            mCaps = event.getAction() == KeyEvent.ACTION_DOWN;
        }
    }


    /**
     * 将keyCode转为char
     *
     * @param caps    是不是大写
     * @param keyCode 按键
     * @return 按键对应的char
     */
    private char getInputCode(boolean caps, int keyCode)
    {
        if (keyCode >= KeyEvent.KEYCODE_A && keyCode <= KeyEvent.KEYCODE_Z)
        {
            return (char) ((caps ? 'A' : 'a') + keyCode - KeyEvent.KEYCODE_A);
        }
        else
        {
            return keyValue(caps, keyCode);
        }
    }


    /**
     * 按键对应的char表
     */
    private char keyValue(boolean caps, int keyCode)
    {
        switch (keyCode)
        {
            case KeyEvent.KEYCODE_0:
                return caps ? ')' : '0';
            case KeyEvent.KEYCODE_1:
                return caps ? '!' : '1';
            case KeyEvent.KEYCODE_2:
                return caps ? '@' : '2';
            case KeyEvent.KEYCODE_3:
                return caps ? '#' : '3';
            case KeyEvent.KEYCODE_4:
                return caps ? '$' : '4';
            case KeyEvent.KEYCODE_5:
                return caps ? '%' : '5';
            case KeyEvent.KEYCODE_6:
                return caps ? '^' : '6';
            case KeyEvent.KEYCODE_7:
                return caps ? '&' : '7';
            case KeyEvent.KEYCODE_8:
                return caps ? '*' : '8';
            case KeyEvent.KEYCODE_9:
                return caps ? '(' : '9';
            case KeyEvent.KEYCODE_NUMPAD_0:
                return '0';
            case KeyEvent.KEYCODE_NUMPAD_1:
                return '1';
            case KeyEvent.KEYCODE_NUMPAD_2:
                return '2';
            case KeyEvent.KEYCODE_NUMPAD_3:
                return '3';
            case KeyEvent.KEYCODE_NUMPAD_4:
                return '4';
            case KeyEvent.KEYCODE_NUMPAD_5:
                return '5';
            case KeyEvent.KEYCODE_NUMPAD_6:
                return '6';
            case KeyEvent.KEYCODE_NUMPAD_7:
                return '7';
            case KeyEvent.KEYCODE_NUMPAD_8:
                return '8';
            case KeyEvent.KEYCODE_NUMPAD_9:
                return '9';
            case KeyEvent.KEYCODE_NUMPAD_SUBTRACT:
                return '-';
            case KeyEvent.KEYCODE_MINUS:
                return '_';
            case KeyEvent.KEYCODE_EQUALS:
                return '=';
            case KeyEvent.KEYCODE_NUMPAD_ADD:
                return '+';
            case KeyEvent.KEYCODE_GRAVE:
                return caps ? '~' : '`';
            case KeyEvent.KEYCODE_BACKSLASH:
                return caps ? '|' : '\\';
            case KeyEvent.KEYCODE_LEFT_BRACKET:
                return caps ? '{' : '[';
            case KeyEvent.KEYCODE_RIGHT_BRACKET:
                return caps ? '}' : ']';
            case KeyEvent.KEYCODE_SEMICOLON:
                return caps ? ':' : ';';
            case KeyEvent.KEYCODE_APOSTROPHE:
                return caps ? '"' : '\'';
            case KeyEvent.KEYCODE_COMMA:
                return caps ? '<' : ',';
            case KeyEvent.KEYCODE_PERIOD:
                return caps ? '>' : '.';
            case KeyEvent.KEYCODE_SLASH:
                return caps ? '?' : '/';
            default:
                return 0;
        }
    }
}